home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 126-150 / disk_134 / dme / command.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  12KB  |  427 lines

  1.  
  2. /*
  3.  * COMMAND.C
  4.  *
  5.  *    (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
  6.  *
  7.  * )c             single character (typing)
  8.  * 'c                single character (typing)
  9.  * `string'          string of characters w/ embedded `' allowed!
  10.  * (string)             same thing w/ embedded () allowed!
  11.  *
  12.  * name arg arg      command name. The arguments are interpreted as strings
  13.  *             for the command.
  14.  *
  15.  * $scanf         macro insert scanf'd variable
  16.  * $filename         macro insert current file name
  17.  *
  18.  * Any string arguments not part of a command are considered to be typed
  19.  * text.
  20.  */
  21.  
  22. #include "defs.h"
  23. #include <stdio.h>
  24.  
  25. #define CF_COK    1   /*    Can be executed while in command line mode    */
  26. #define CF_PAR    2   /*    ESCIMM special flag.. save rest of command line */
  27.             /*    so it can be executed after user entry        */
  28.  
  29. extern char *breakout();
  30.  
  31. typedef struct {
  32.    char *name;        /* command name      */
  33.    ubyte args;
  34.    ubyte flags;
  35.    int (*func)();   /* function           */
  36. } COMM;
  37.  
  38. extern int  do_map(),       do_unmap(),     do_up(),        do_down(),
  39.         do_left(),      do_right(),     do_return(),    do_bs(),
  40.         do_del(),       do_esc(),       do_downadd(),   do_lastcolumn(),
  41.         do_firstcolumn(),do_edit(),     do_tab(),       do_backtab(),
  42.         do_save(),      do_saveas(),    do_deline(),    do_insline(),
  43.         do_top(),       do_bottom(),    do_source(),    do_firstnb(),
  44.         do_quit(),      do_find(),      do_page(),      do_savetabs(),
  45.         do_split(),     do_goto(),      do_screentop(), do_screenbottom(),
  46.         do_join(),      do_repeat(),    do_tabstop(),   do_insertmode(),
  47.         do_block(),     do_bdelete(),   do_bcopy(),     do_bmove(),
  48.         do_bsave(),     do_wleft(),     do_wright(),    do_remeol(),
  49.         do_savemap(),   do_toggle(),    do_if(),        do_tlate(),
  50.         do_bsource(),   do_findr(),     do_findstr(),   do_newwindow(),
  51.         do_windowparm(),do_resize(),    do_margin(),    do_wordwrap(),
  52.         do_reformat(),  do_execute(),   do_chfilename(),do_scrollup(),
  53.         do_scrolldown(),do_recall(),    do_scanf(),     do_iconify(),
  54.         do_tomouse(),   do_refs(),      do_arpload(),   do_arpsave();
  55.  
  56. extern int  do_menu(), do_menuclear(), do_menuadd(), do_menudel(),
  57.         do_menudelhdr(), do_menuon(), do_menuoff();
  58.  
  59. /*
  60.  *  WLEFT/WRIGHT will check command line mode themselves, and thus can
  61.  *  be marked flags=1 even though they can change the line number.
  62.  *
  63.  *  No more than 255 commands may exist unless you change the type of hindex[]
  64.  *
  65.  *  Command names MUST be sorted by their first character
  66.  */
  67.  
  68. unsigned char hindex[26];   /*    alpha hash into table    */
  69.  
  70.     /*      args flags    */
  71.  
  72. COMM Comm[] = {
  73.     "arpload",       0,      0, do_arpload,
  74.     "arpsave",       0,      0, do_arpsave,
  75.     "back",          0, CF_COK, do_bs,
  76.     "backtab",       0, CF_COK, do_backtab,
  77.     "bcopy",         0,      0, do_bcopy,
  78.     "bdelete",       0,      0, do_bdelete,
  79.     "block",         0,      0, do_block,    /* checks com name for mode */
  80.     "bmove",         0,      0, do_bmove,
  81.     "bottom",        0,      0, do_bottom,
  82.     "bs",            0, CF_COK, do_bs,
  83.     "bsave",         1, CF_COK, do_bsave,
  84.     "bsource",       0,      0, do_bsource,
  85.     "chfilename",    1,      0, do_chfilename,
  86.     "del",           0, CF_COK, do_del,
  87.     "deline",        0,      0, do_deline,
  88.     "down",          0,      0, do_down,
  89.     "downadd",       0,      0, do_downadd,
  90.     "esc",           0, CF_COK, do_esc,
  91.     "escimm",        1, CF_PAR, do_esc,
  92.     "execute",       1,      0, do_execute,
  93.     "find",          1,      0, do_find,     /* checks com name for mode */
  94.     "findr",         2,      0, do_findr,    /* checks com name for mode */
  95.     "findstr",       1, CF_COK, do_findstr,  /* checks com name for mode */
  96.     "first",         0, CF_COK, do_firstcolumn,
  97.     "firstnb",       0, CF_COK, do_firstnb,
  98.     "goto",          1,      0, do_goto,
  99.     "height",        1, CF_COK, do_windowparm,
  100.     "iconify",       0,      0, do_iconify,
  101.     "if",            2, CF_COK, do_if,
  102.     "ifelse",        3, CF_COK, do_if,
  103.     "insertmode",    1, CF_COK, do_insertmode,
  104.     "insfile",       1,      0, do_edit,
  105.     "insline",       0,      0, do_insline,
  106.     "join",          0,      0, do_join,
  107.     "last",          0, CF_COK, do_lastcolumn,
  108.     "left",          0, CF_COK, do_left,
  109.     "leftedge",      1, CF_COK, do_windowparm,
  110.     "map",           2, CF_COK, do_map,
  111.     "margin",        1, CF_COK, do_margin,
  112.     "menuon",        0,      0, do_menuon,
  113.     "menuoff",       0,      0, do_menuoff,
  114.     "menuadd",       3,      0, do_menuadd,
  115.     "menudel",       2,      0, do_menudel,
  116.     "menudelhdr",    1,      0, do_menudelhdr,
  117.     "menuclear",     0,      0, do_menuclear,
  118.     "newfile",       1,      0, do_edit,     /* checks com name for mode */
  119.     "newwindow",     0,      0, do_newwindow,
  120.     "next",          0,      0, do_find,
  121.     "nextr",         0,      0, do_findr,
  122.     "pagedown",      0,      0, do_page,
  123.     "pageset",       1,      0, do_page,
  124.     "pageup",        0,      0, do_page,
  125.     "prev",          0,      0, do_find,
  126.     "prevr",         0,      0, do_findr,
  127.     "quit",          0,      0, do_quit,
  128.     "recall",        0, CF_COK, do_recall,
  129.     "ref",           0,      0, do_refs,
  130.     "reformat",      0,      0, do_reformat,
  131.     "remeol",        0, CF_COK, do_remeol,
  132.     "repeat",        2, CF_COK, do_repeat,
  133.     "repstr",        1, CF_COK, do_findstr,
  134.     "resettoggle",   1, CF_COK, do_toggle,
  135.     "resize",        2,      0, do_resize,
  136.     "return",        0, CF_COK, do_return,   /* special meaning in command line mode */
  137.     "right",         0, CF_COK, do_right,
  138.     "saveas",        1, CF_COK, do_saveas,
  139.     "savemap",       1, CF_COK, do_savemap,  /* checks com name for mode */
  140.     "saveold",       0, CF_COK, do_save,
  141.     "savesmap",      1, CF_COK, do_savemap,
  142.     "savetabs",      1, CF_COK, do_savetabs,
  143.     "scanf",         1, CF_COK, do_scanf,
  144.     "screenbottom",  0,      0, do_screenbottom,
  145.     "screentop",     0,      0, do_screentop,
  146.     "scrollup",      0,      0, do_scrollup,
  147.     "scrolldown",    0,      0, do_scrolldown,
  148.     "settoggle",     1, CF_COK, do_toggle,
  149.     "source",        1, CF_COK, do_source,
  150.     "split",         0,      0, do_split,
  151.     "tab",           0, CF_COK, do_tab,
  152.     "tabstop",       1, CF_COK, do_tabstop,
  153.     "tlate",         1, CF_COK, do_tlate,
  154.     "tmpheight",     1, CF_COK, do_windowparm,
  155.     "tmpwidth",      1, CF_COK, do_windowparm,
  156.     "toggle",        1, CF_COK, do_toggle,
  157.     "tomouse",       0,      0, do_tomouse,
  158.     "top",           0,      0, do_top,
  159.     "topedge",       1, CF_COK, do_windowparm,
  160.     "unblock",       0,      0, do_block,
  161.     "unmap",         1, CF_COK, do_unmap,
  162.     "up",            0,      0, do_up,
  163.     "while",         2, CF_COK, do_if,
  164.     "width",         1, CF_COK, do_windowparm,
  165.     "wleft",         0, CF_COK, do_wleft,
  166.     "wordwrap",      1, CF_COK, do_wordwrap,
  167.     "wright",        0, CF_COK, do_wright,
  168.     NULL, 0, 0, NULL
  169. };
  170.  
  171. init_command()
  172. {
  173.     register short hi;
  174.     register COMM *comm;
  175.  
  176.     hi = sizeof(Comm)/sizeof(Comm[0]) - 2;
  177.     comm = Comm + hi;
  178.  
  179.     while (hi >= 0) {
  180.     hindex[comm->name[0] - 'a'] = hi;
  181.     --hi;
  182.     --comm;
  183.     }
  184. }
  185.  
  186. do_command(str)
  187. char *str;
  188. {
  189.     register char *arg;
  190.     char quoted;
  191.     register short i, j;
  192.     static int level;
  193.  
  194.     if (++level > 20) {
  195.     title("Recursion Too Deep!");
  196.     --level;
  197.     return(0);
  198.     }
  199.     while (arg = breakout(&str, "ed)) {
  200.     if (quoted) {
  201.         text_write(arg);
  202.         continue;
  203.     }
  204.     for (i = 0; arg[i]; ++i) {
  205.         if (arg[i] >= 'A' && arg[i] <= 'Z')
  206.         arg[i] += 'a' - 'A';
  207.     }
  208.     if (arg[0] >= 'a' && arg[0] <= 'z') {
  209.         register COMM *comm = &Comm[hindex[arg[0]-'a']];
  210.         for (; comm->name && comm->name[0] == arg[0]; ++comm) {
  211.         if (strcmp(arg, comm->name) == 0) {
  212.             av[0] = (ubyte *)comm->name;
  213.             for (j = 1; j <= comm->args; ++j) {
  214.             av[j] = (ubyte *)breakout(&str, "ed);
  215.             if (!av[j]) {
  216.                 title("Bad argument");
  217.                 --level;
  218.                 return(0);
  219.             }
  220.             if (av[j][0] == '$')
  221.                 av[j] = (ubyte *)String;
  222.             }
  223.             if ((comm->flags & CF_COK) || !Comlinemode) {
  224.             if (comm->flags & CF_PAR) {
  225.                 if (Partial)
  226.                 free(Partial);
  227.                 Partial = (char *)malloc(strlen(str)+1);
  228.                 strcpy(Partial, str);
  229.                 str += strlen(str);     /*  skip string */
  230.             }
  231.             (*comm->func)(-1);
  232.             }
  233.             if (Abortcommand)
  234.             goto fail;
  235.             goto loop;
  236.         }
  237.         }
  238.     }
  239.  
  240.     /* Command not found, check for macro    */
  241.  
  242.     {
  243.         char *str;
  244.         int ret;
  245.         if ((str = keyspectomacro(arg)) || (str = menutomacro(arg))) {
  246.         str = (char *)strcpy(malloc(strlen(str)+1), str);
  247.         ret = do_command(str);
  248.         free(str);
  249.         if (ret)
  250.             goto loop;
  251.         goto fail;
  252.         }
  253.     }
  254.  
  255.     title("Unknown Command");
  256. fail:
  257.     --level;
  258.     return(0);
  259. loop:
  260.     ;
  261.     }
  262.     --level;
  263.     return(1);
  264. }
  265.  
  266.  
  267. do_source()
  268. {
  269.     char buf[256];
  270.     long xfi;
  271.     register char *str;
  272.  
  273.     if (xfi = xfopen(av[1], "r", 512)) {
  274.     while (xfgets(xfi, buf, 256) >= 0) {
  275.         if (buf[0] == '#')
  276.         continue;
  277.         for (str = buf; *str; ++str) {
  278.         if (*str == 9)
  279.             *str = ' ';
  280.         }
  281.         do_command(buf);
  282.     }
  283.     xfclose(xfi);
  284.     } else {
  285.     if (av[0])
  286.         title("File not found");
  287.     }
  288. }
  289.  
  290.  
  291. do_quit()
  292. {
  293.     extern char Quitflag;
  294.  
  295.     Quitflag = 1;
  296. }
  297.  
  298. do_execute()
  299. {
  300.     Execute(av[1], 0, 0);
  301. }
  302.  
  303. /*
  304.  * repeat X command
  305.  *
  306.  * Since repeat takes up 512+ stack, it should not be nested more than
  307.  * twice.
  308.  *
  309.  * (if X is not a number it can be abbr. with 2 chars)
  310.  *
  311.  * X =    N     -number of repeats
  312.  *    line  -current line # (lines begin at 1)
  313.  *    lbot  -#lines to the bottom, inc. current
  314.  *    cleft -column # (columns begin at 0)
  315.  *        (thus is also chars to the left)
  316.  *    cright-#chars to eol, including current char
  317.  *    tr    -#char positions to get to next tab stop
  318.  *    tl    -#char positions to get to next backtab stop
  319.  */
  320.  
  321. #define SC(a,b) ((a)<<8|(b))
  322.  
  323. do_repeat()
  324. {
  325.     register ubyte *ptr = av[1];
  326.     register unsigned long n;
  327.     char buf1[256];
  328.     char buf2[256];
  329.  
  330.     breakreset();
  331.     strcpy(buf1, av[2]);
  332.     switch((ptr[0]<<8)+ptr[1]) {
  333.     case SC('l','i'):
  334.     n = text_lineno();
  335.     break;
  336.     case SC('l','b'):
  337.     n = text_lines() - text_lineno() + 1;
  338.     break;
  339.     case SC('c','l'):
  340.     n = text_colno();
  341.     break;
  342.     case SC('c','r'):
  343.     n = text_cols() - text_colno();
  344.     break;
  345.     case SC('t','r'):
  346.     n = text_tabsize()-(text_colno() % text_tabsize());
  347.     break;
  348.     case SC('t','l'):
  349.     n = text_colno() % text_tabsize();
  350.     if (n == 0)
  351.         n = text_tabsize();
  352.     break;
  353.     default:
  354.     n = atoi(av[1]);
  355.     break;
  356.     }
  357.     while (n > 0) {
  358.     strcpy(buf2, buf1);
  359.     if (do_command(buf2) == 0 || breakcheck()) {
  360.         Abortcommand = 1;
  361.         break;
  362.     }
  363.     --n;
  364.     }
  365. }
  366.  
  367.  
  368. char *
  369. breakout(ptr, quoted)
  370. register char **ptr;
  371. char *quoted;
  372. {
  373.     register char *str = *ptr;
  374.     register char *base = str;
  375.  
  376.     *quoted = 0;
  377.     while (*str == ' ')
  378.     ++str;
  379.     if (!*str)
  380.     return(NULL);
  381.     if (*str == '\'' || *str == ')') {
  382.     if (str[1]) {
  383.         *quoted = 1;
  384.         base = str + 1;
  385.         if (str[2])
  386.         ++str;
  387.         *str = '\0';
  388.         *ptr = str;
  389.         return(base);
  390.     }
  391.     return(NULL);
  392.     }
  393.     if (*str == '`' || *str == '(') {
  394.     short count = 1;
  395.     char opc = *str;
  396.     char clc = (opc == '(') ? ')' : '\'';
  397.  
  398.     base = ++str;
  399.     while (*str && count) {
  400.         if (*str == opc)
  401.         ++count;
  402.         if (*str == clc)
  403.         --count;
  404.         ++str;
  405.     }
  406.     if (count == 0) {
  407.         --str;
  408.         *quoted = 1;
  409.         *str = '\0';
  410.         *ptr = str + 1;
  411.         return(base);
  412.     }
  413.     }
  414.     base = str;
  415.     while (*str && *str != ' ')
  416.     ++str;
  417.     if (*str) {
  418.     *str = '\0';
  419.     *ptr = str + 1;
  420.     return(base);
  421.     }
  422.     *ptr = str;
  423.     return(base);
  424. }
  425.  
  426.  
  427.